// 停止传播
export const STOP_PROPGATION = 'stop_propagation'

/**
 * 信号发射器
 */
export class Signal{
  constructor(){
    this.receivers = [];
    this.modifyCount = 0;
  }

  /**
   * 添加一个监听者
   * @param {Function}} receiver 
   * @param {This} scope 
   */
  add(receiver, scope = null){
    assert(receiver, '监听者为空！');
    this.receivers.push({ receiver, scope });
    this.modifyCount++;
  }

  /**
   * 发送信号
   */
  dispatch(){
    const modifyState = this.modifyCount;
    const n = this.receivers.length;

    for(let i = 0; i < n; i++){
      const { receiver, scope } = this.receivers[i]
      if(receiver.apply(scope, arguments) === STOP_PROPGATION){
        return STOP_PROPGATION;
      }

      // 发送中，如果监听者发生了变化，将不再传播
      if(modifyState !== this.modifyCount){
        return STOP_PROPGATION;
      }
    }
  }

  /**
   * 删除指定监听者
   * @param {Function} receiver 
   */
  remove(receiver){
    let index = null;
    const n = this.receivers.length;
    for(let i = 0; i < n; i++){
      if(this.receivers[i].receiver === receiver){
        index = i;
        break
      }
    }
    assert(index !== null, '监听者不在列表中')
    this.receivers.splice(index, 1);
    this.modifyCount++;
  }

  /**
   * 删除所有的监听者
   */
  removeAll(){
    this.receivers = [];
    this.modifyCount++;
  }
}